Skip to content

Conversation

@Benjamin-Nussbaum
Copy link
Contributor

@Benjamin-Nussbaum Benjamin-Nussbaum commented Nov 20, 2025

Consolidate Instrument Protocol types to allow proper type checking on the client side.

This change removes the need for runtime asserts and other nonstandard checks.

How have these changes been tested?

Existing tests pass running uv run scripts/test.

  • My code follows the code style of this project.
  • All new and existing tests pass.

@Benjamin-Nussbaum Benjamin-Nussbaum marked this pull request as ready for review November 20, 2025 21:04
Copy link
Collaborator

@marcosfrenkel marcosfrenkel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot start the FastAPI server. Not sure if I am missing something. This is the error I get (copied whole traceback just in case):


   FastAPI   Starting development server 🚀
 
             Searching for package file structure from directories with __init__.py files

╭─────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────────────────────────────────────╮
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi_cli/cli.py:307 in dev                                                                                         │
│                                                                                                                                                                                                         │
│   304 │                                                                                        ╭────────────────────────── locals ───────────────────────────╮                                          │
│   305 │   Otherwise, it uses the first [bold]FastAPI[/bold] app found in the imported module o │                 app = None                                  │                                          │
│   306 │   """                                                                                  │          entrypoint = None                                  │                                          │
│ ❱ 307 │   _run(                                                                                │ forwarded_allow_ips = None                                  │                                          │
│   308 │   │   path=path,                                                                       │                host = '0.0.0.0'                             │                                          │
│   309 │   │   host=host,                                                                       │                path = PosixPath('src/pqnstack/app/main.py') │                                          │
│   310 │   │   port=port,                                                                       │                port = 8000                                  │                                          │
│                                                                                                │       proxy_headers = True                                  │                                          │
│                                                                                                │              reload = True                                  │                                          │
│                                                                                                │           root_path = ''                                    │                                          │
│                                                                                                ╰─────────────────────────────────────────────────────────────╯                                          │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi_cli/cli.py:142 in _run                                                                                        │
│                                                                                                                                                                                                         │
│   139 │   │   try:                                                                             ╭──────────────────────────────────── locals ────────────────────────────────────╮                       │
│   140 │   │   │   # Resolve import data with priority: CLI path/app > config entrypoint > auto │                 app = None                                                     │                       │
│   141 │   │   │   if path or app:                                                              │             command = 'dev'                                                    │                       │
│ ❱ 142 │   │   │   │   import_data = get_import_data(path=path, app_name=app)                   │              config = FastAPIConfig(entrypoint=None)                           │                       │
│   143 │   │   │   elif config.entrypoint:                                                      │          entrypoint = None                                                     │                       │
│   144 │   │   │   │   import_data = get_import_data_from_import_string(config.entrypoint)      │ forwarded_allow_ips = None                                                     │                       │
│   145 │   │   │   else:                                                                        │                host = '0.0.0.0'                                                │                       │
│                                                                                                │                path = PosixPath('src/pqnstack/app/main.py')                    │                       │
│                                                                                                │                port = 8000                                                     │                       │
│                                                                                                │       proxy_headers = True                                                     │                       │
│                                                                                                │              reload = True                                                     │                       │
│                                                                                                │           root_path = ''                                                       │                       │
│                                                                                                │         server_type = 'development'                                            │                       │
│                                                                                                │             toolkit = <rich_toolkit.toolkit.RichToolkit object at 0x1106ca390> │                       │
│                                                                                                │             workers = None                                                     │                       │
│                                                                                                ╰────────────────────────────────────────────────────────────────────────────────╯                       │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi_cli/discover.py:126 in get_import_data                                                                        │
│                                                                                                                                                                                                         │
│   123 │   │   raise FastAPICLIException(f"Path does not exist {path}")                                                                                                                                  │
│   124 │   mod_data = get_module_data_from_path(path)                                                                                                                                                    │
│   125 │   sys.path.insert(0, str(mod_data.extra_sys_path))                                                                                                                                              │
│ ❱ 126 │   use_app_name = get_app_name(mod_data=mod_data, app_name=app_name)                                                                                                                             │
│   127 │                                                                                                                                                                                                 │
│   128 │   import_string = f"{mod_data.module_import_str}:{use_app_name}"                                                                                                                                │
│   129                                                                                                                                                                                                   │
│                                                                                                                                                                                                         │
│ ╭──────────────────────────────────────────────── locals ─────────────────────────────────────────────────╮                                                                                             │
│ │ app_name = None                                                                                         │                                                                                             │
│ │ mod_data = ModuleData(                                                                                  │                                                                                             │
│ │            │   module_import_str='pqnstack.app.main',                                                   │                                                                                             │
│ │            │   extra_sys_path=PosixPath('/Users/marcosf2/Documents/github/PQN/pqn-stack/src'),          │                                                                                             │
│ │            │   module_paths=[                                                                           │                                                                                             │
│ │            │   │   PosixPath('/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack'),            │                                                                                             │
│ │            │   │   PosixPath('/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app'),        │                                                                                             │
│ │            │   │   PosixPath('/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py') │                                                                                             │
│ │            │   ]                                                                                        │                                                                                             │
│ │            )                                                                                            │                                                                                             │
│ │     path = PosixPath('src/pqnstack/app/main.py')                                                        │                                                                                             │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                                                                             │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi_cli/discover.py:70 in get_app_name                                                                            │
│                                                                                                                                                                                                         │
│    67                                                                                                                                                                                                   │
│    68 def get_app_name(*, mod_data: ModuleData, app_name: Union[str, None] = None) -> str:                                                                                                              │
│    69 │   try:                                                                                                                                                                                          │
│ ❱  70 │   │   mod = importlib.import_module(mod_data.module_import_str)                                                                                                                                 │
│    71 │   except (ImportError, ValueError) as e:                                                                                                                                                        │
│    72 │   │   logger.error(f"Import error: {e}")                                                                                                                                                        │
│    73 │   │   logger.warning(                                                                                                                                                                           │
│                                                                                                                                                                                                         │
│ ╭──────────────────────────────────────────────── locals ─────────────────────────────────────────────────╮                                                                                             │
│ │ app_name = None                                                                                         │                                                                                             │
│ │ mod_data = ModuleData(                                                                                  │                                                                                             │
│ │            │   module_import_str='pqnstack.app.main',                                                   │                                                                                             │
│ │            │   extra_sys_path=PosixPath('/Users/marcosf2/Documents/github/PQN/pqn-stack/src'),          │                                                                                             │
│ │            │   module_paths=[                                                                           │                                                                                             │
│ │            │   │   PosixPath('/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack'),            │                                                                                             │
│ │            │   │   PosixPath('/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app'),        │                                                                                             │
│ │            │   │   PosixPath('/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py') │                                                                                             │
│ │            │   ]                                                                                        │                                                                                             │
│ │            )                                                                                            │                                                                                             │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                                                                             │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/.local/share/uv/python/cpython-3.12.8-macos-aarch64-none/lib/python3.12/importlib/__init__.py:90 in import_module                                                                       │
│                                                                                                                                                                                                         │
│    87 │   │   │   if character != '.':                                                         ╭─────────── locals ────────────╮                                                                        │
│    88 │   │   │   │   break                                                                    │   level = 0                   │                                                                        │
│    89 │   │   │   level += 1                                                                   │    name = 'pqnstack.app.main' │                                                                        │
│ ❱  90 │   return _bootstrap._gcd_import(name[level:], package, level)                          │ package = None                │                                                                        │
│    91                                                                                          ╰───────────────────────────────╯                                                                        │
│    92                                                                                                                                                                                                   │
│    93 _RELOADING = {}                                                                                                                                                                                   │
│ in _gcd_import:1387                                                                                                                                                                                     │
│ ╭─────────── locals ────────────╮                                                                                                                                                                       │
│ │   level = 0                   │                                                                                                                                                                       │
│ │    name = 'pqnstack.app.main' │                                                                                                                                                                       │
│ │ package = None                │                                                                                                                                                                       │
│ ╰───────────────────────────────╯                                                                                                                                                                       │
│ in _find_and_load:1360                                                                                                                                                                                  │
│ ╭──────────────── locals ─────────────────╮                                                                                                                                                             │
│ │ module = <object object at 0x1049e4060> │                                                                                                                                                             │
│ │   name = 'pqnstack.app.main'            │                                                                                                                                                             │
│ ╰─────────────────────────────────────────╯                                                                                                                                                             │
│ in _find_and_load_unlocked:1331                                                                                                                                                                         │
│ ╭────────────────────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │         child = 'main'                                                                                                                                                                              │ │
│ │          name = 'pqnstack.app.main'                                                                                                                                                                 │ │
│ │        parent = 'pqnstack.app'                                                                                                                                                                      │ │
│ │ parent_module = <module 'pqnstack.app' from '/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/__init__.py'>                                                                          │ │
│ │   parent_spec = ModuleSpec(name='pqnstack.app', loader=<_frozen_importlib_external.SourceFileLoader object at 0x1106e0830>,                                                                         │ │
│ │                 origin='/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/__init__.py',                                                                                               │ │
│ │                 submodule_search_locations=['/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app'])                                                                                     │ │
│ │          path = ['/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app']                                                                                                                 │ │
│ │          spec = ModuleSpec(name='pqnstack.app.main', loader=<_frozen_importlib_external.SourceFileLoader object at 0x1106e0b90>,                                                                    │ │
│ │                 origin='/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py')                                                                                                   │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ in _load_unlocked:935                                                                                                                                                                                   │
│ ╭────────────────────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ module = <module 'pqnstack.app.main' from '/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py'>                                                                                │ │
│ │   spec = ModuleSpec(name='pqnstack.app.main', loader=<_frozen_importlib_external.SourceFileLoader object at 0x1106e0b90>,                                                                           │ │
│ │          origin='/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py')                                                                                                          │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ in exec_module:999                                                                                                                                                                                      │
│ ╭──────────────────────────────────────────────────────────────── locals ────────────────────────────────────────────────────────────────╮                                                              │
│ │   code = <code object <module> at 0x110700030, file "/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py", line 1> │                                                              │
│ │ module = <module 'pqnstack.app.main' from '/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py'>                   │                                                              │
│ │   self = <_frozen_importlib_external.SourceFileLoader object at 0x1106e0b90>                                                           │                                                              │
│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                                              │
│ in _call_with_frames_removed:488                                                                                                                                                                        │
│ ╭────────────────────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ args = (                                                                                                                                                                                            │ │
│ │        │   <code object <module> at 0x110700030, file "/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py", line 1>,                                                           │ │
│ │        │   {                                                                                                                                                                                        │ │
│ │        │   │   '__name__': 'pqnstack.app.main',                                                                                                                                                     │ │
│ │        │   │   '__doc__': None,                                                                                                                                                                     │ │
│ │        │   │   '__package__': 'pqnstack.app',                                                                                                                                                       │ │
│ │        │   │   '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x1106e0b90>,                                                                                                   │ │
│ │        │   │   '__spec__': ModuleSpec(name='pqnstack.app.main', loader=<_frozen_importlib_external.SourceFileLoader object at 0x1106e0b90>,                                                         │ │
│ │        origin='/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py'),                                                                                                           │ │
│ │        │   │   '__file__': '/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py',                                                                                               │ │
│ │        │   │   '__cached__': '/Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/__pycache__/main'+16,                                                                                 │ │
│ │        │   │   '__builtins__': {                                                                                                                                                                    │ │
│ │        │   │   │   '__name__': 'builtins',                                                                                                                                                          │ │
│ │        │   │   │   '__doc__': 'Built-in functions, types, exceptions, and other objects.\n\nThis module provides '+346,                                                                             │ │
│ │        │   │   │   '__package__': '',                                                                                                                                                               │ │
│ │        │   │   │   '__loader__': <class '_frozen_importlib.BuiltinImporter'>,                                                                                                                       │ │
│ │        │   │   │   '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>, origin='built-in'),                                                                  │ │
│ │        │   │   │   '__build_class__': <built-in function __build_class__>,                                                                                                                          │ │
│ │        │   │   │   '__import__': <built-in function __import__>,                                                                                                                                    │ │
│ │        │   │   │   'abs': <built-in function abs>,                                                                                                                                                  │ │
│ │        │   │   │   'all': <built-in function all>,                                                                                                                                                  │ │
│ │        │   │   │   'any': <built-in function any>,                                                                                                                                                  │ │
│ │        │   │   │   ... +147                                                                                                                                                                         │ │
│ │        │   │   },                                                                                                                                                                                   │ │
│ │        │   │   'logging': <module 'logging' from '/Users/marcosf2/.local/share/uv/python/cpython-3.12.8-macos-aarch64-none/lib/python3.12/logging/__init__.py'>,                                    │ │
│ │        │   │   'FastAPI': <class 'fastapi.applications.FastAPI'>,                                                                                                                                   │ │
│ │        │   │   ... +1                                                                                                                                                                               │ │
│ │        │   }                                                                                                                                                                                        │ │
│ │        )                                                                                                                                                                                            │ │
│ │    f = <built-in function exec>                                                                                                                                                                     │ │
│ │ kwds = {}                                                                                                                                                                                           │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/main.py:6 in <module>                                                                                                                   │
│                                                                                                                                                                                                         │
│    3 from fastapi import FastAPI                                                                                                                                                                        │
│    4 from fastapi.middleware.cors import CORSMiddleware                                                                                                                                                 │
│    5                                                                                                                                                                                                    │
│ ❱  6 from pqnstack.app.api.main import api_router                                                                                                                                                       │
│    7                                                                                                                                                                                                    │
│    8 logging.basicConfig(level=logging.DEBUG)                                                                                                                                                           │
│    9 logger = logging.getLogger(__name__)                                                                                                                                                               │
│                                                                                                                                                                                                         │
│ ╭──────────────────────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────────────────────╮                                                     │
│ │ logging = <module 'logging' from '/Users/marcosf2/.local/share/uv/python/cpython-3.12.8-macos-aarch64-none/lib/python3.12/logging/__init__.py'> │                                                     │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                                     │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/api/main.py:3 in <module>                                                                                                               │
│                                                                                                                                                                                                         │
│    1 from fastapi import APIRouter                                                                                                                                                                      │
│    2                                                                                                                                                                                                    │
│ ❱  3 from pqnstack.app.api.routes import chsh                                                                                                                                                           │
│    4 from pqnstack.app.api.routes import qkd                                                                                                                                                            │
│    5 from pqnstack.app.api.routes import rng                                                                                                                                                            │
│    6 from pqnstack.app.api.routes import serial                                                                                                                                                         │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/src/pqnstack/app/api/routes/chsh.py:114 in <module>                                                                                                      │
│                                                                                                                                                                                                         │
│   111 │   return chsh_value, chsh_error                                                                                                                                                                 │
│   112                                                                                                                                                                                                   │
│   113                                                                                                                                                                                                   │
│ ❱ 114 @router.post("/")                                                                                                                                                                                 │
│   115 async def chsh(                                                                                                                                                                                   │
│   116 │   basis: tuple[float, float],                                                                                                                                                                   │
│   117 │   follower_node_address: str,                                                                                                                                                                   │
│                                                                                                                                                                                                         │
│ ╭───────────────────────────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────────────────────────╮                                            │
│ │     ClientDep = ClientDep                                                                                                                                │                                            │
│ │        logger = <Logger pqnstack.app.api.routes.chsh (WARNING)>                                                                                          │                                            │
│ │       logging = <module 'logging' from '/Users/marcosf2/.local/share/uv/python/cpython-3.12.8-macos-aarch64-none/lib/python3.12/logging/__init__.py'>    │                                            │
│ │        router = <fastapi.routing.APIRouter object at 0x1107d3560>                                                                                        │                                            │
│ │      settings = Settings(                                                                                                                                │                                            │
│ │                 │   router_name='router1',                                                                                                               │                                            │
│ │                 │   router_address='172.30.63.109',                                                                                                      │                                            │
│ │                 │   router_port=5555,                                                                                                                    │                                            │
│ │                 │   chsh_settings=CHSHSettings(                                                                                                          │                                            │
│ │                 │   │   hwp=('loomis_server', 'signal_hwp'),                                                                                             │                                            │
│ │                 │   │   request_hwp=('loomis_server', 'signal_hwp'),                                                                                     │                                            │
│ │                 │   │   measurement_config=MeasurementConfig(integration_time_s=1.0, binwidth_ps=500, channel1=1, channel2=2, dark_count=0)              │                                            │
│ │                 │   ),                                                                                                                                   │                                            │
│ │                 │   qkd_settings=QKDSettings(                                                                                                            │                                            │
│ │                 │   │   hwp=('loomis_server', 'signal_hwp'),                                                                                             │                                            │
│ │                 │   │   request_hwp=('loomis_server', 'signal_hwp'),                                                                                     │                                            │
│ │                 │   │   bitstring_length=6,                                                                                                              │                                            │
│ │                 │   │   discriminating_threshold=10,                                                                                                     │                                            │
│ │                 │   │   measurement_config=MeasurementConfig(integration_time_s=1.0, binwidth_ps=500, channel1=1, channel2=2, dark_count=0)              │                                            │
│ │                 │   ),                                                                                                                                   │                                            │
│ │                 │   bell_state=<BellState.Phi_plus: 0>,                                                                                                  │                                            │
│ │                 │   timetagger=('mini_pc', 'tagger'),                                                                                                    │                                            │
│ │                 │   rotary_encoder_address='/dev/tty.usbmodem101',                                                                                       │                                            │
│ │                 │   rotary_encoder=None                                                                                                                  │                                            │
│ │                 )                                                                                                                                        │                                            │
│ │         state = NodeState(                                                                                                                               │                                            │
│ │                 │   chsh_request_basis=[22.5, 67.5],                                                                                                     │                                            │
│ │                 │   qkd_basis_list=[                                                                                                                     │                                            │
│ │                 │   │   <QKDEncodingBasis.DA: 1>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.DA: 1>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.DA: 1>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.DA: 1>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.DA: 1>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.DA: 1>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.HV: 0>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.HV: 0>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.HV: 0>,                                                                                                        │                                            │
│ │                 │   │   <QKDEncodingBasis.HV: 0>,                                                                                                        │                                            │
│ │                 │   │   ... +1                                                                                                                           │                                            │
│ │                 │   ],                                                                                                                                   │                                            │
│ │                 │   qkd_bit_list=[],                                                                                                                     │                                            │
│ │                 │   qkd_resulting_bit_list=[],                                                                                                           │                                            │
│ │                 │   qkd_request_basis_list=[],                                                                                                           │                                            │
│ │                 │   qkd_request_bit_list=[]                                                                                                              │                                            │
│ │                 )                                                                                                                                        │                                            │
│ │        status = <module 'starlette.status' from '/Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/starlette/status.py'> │                                            │
│ │ TYPE_CHECKING = False                                                                                                                                    │                                            │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                            │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi/routing.py:1078 in decorator                                                                                  │
│                                                                                                                                                                                                         │
│   1075 │   │   ),                                                                               ╭────────────────────────────────────────────── locals ───────────────────────────────────────────────╮ │
│   1076 │   ) -> Callable[[DecoratedCallable], DecoratedCallable]:                               │                       callbacks = None                                                              │ │
│   1077 │   │   def decorator(func: DecoratedCallable) -> DecoratedCallable:                     │                    dependencies = None                                                              │ │
│ ❱ 1078 │   │   │   self.add_api_route(                                                          │                      deprecated = None                                                              │ │
│   1079 │   │   │   │   path,                                                                    │                     description = None                                                              │ │
│   1080 │   │   │   │   func,                                                                    │     generate_unique_id_function = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cf20> │ │
│   1081 │   │   │   │   response_model=response_model,                                           │               include_in_schema = True                                                              │ │
│                                                                                                 │                         methods = ['POST']                                                          │ │
│                                                                                                 │                            name = None                                                              │ │
│                                                                                                 │                   openapi_extra = None                                                              │ │
│                                                                                                 │                    operation_id = None                                                              │ │
│                                                                                                 │                            path = '/'                                                               │ │
│                                                                                                 │                  response_class = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cef0> │ │
│                                                                                                 │            response_description = 'Successful Response'                                             │ │
│                                                                                                 │                  response_model = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cec0> │ │
│                                                                                                 │         response_model_by_alias = True                                                              │ │
│                                                                                                 │          response_model_exclude = None                                                              │ │
│                                                                                                 │ response_model_exclude_defaults = False                                                             │ │
│                                                                                                 │     response_model_exclude_none = False                                                             │ │
│                                                                                                 │    response_model_exclude_unset = False                                                             │ │
│                                                                                                 │          response_model_include = None                                                              │ │
│                                                                                                 │                       responses = None                                                              │ │
│                                                                                                 │                            self = <fastapi.routing.APIRouter object at 0x1107d3560>                 │ │
│                                                                                                 │                     status_code = None                                                              │ │
│                                                                                                 │                         summary = None                                                              │ │
│                                                                                                 │                            tags = None                                                              │ │
│                                                                                                 ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi/routing.py:1017 in add_api_route                                                                              │
│                                                                                                                                                                                                         │
│   1014 │   │   current_generate_unique_id = get_value_or_default(                               ╭────────────────────────────────────────────── locals ───────────────────────────────────────────────╮ │
│   1015 │   │   │   generate_unique_id_function, self.generate_unique_id_function                │                       callbacks = None                                                              │ │
│   1016 │   │   )                                                                                │              combined_responses = {}                                                                │ │
│ ❱ 1017 │   │   route = route_class(                                                             │               current_callbacks = []                                                                │ │
│   1018 │   │   │   self.prefix + path,                                                          │            current_dependencies = []                                                                │ │
│   1019 │   │   │   endpoint=endpoint,                                                           │      current_generate_unique_id = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cf20> │ │
│   1020 │   │   │   response_model=response_model,                                               │          current_response_class = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cef0> │ │
│                                                                                                 │                    current_tags = ['chsh']                                                          │ │
│                                                                                                 │                    dependencies = None                                                              │ │
│                                                                                                 │                      deprecated = None                                                              │ │
│                                                                                                 │                     description = None                                                              │ │
│                                                                                                 │     generate_unique_id_function = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cf20> │ │
│                                                                                                 │               include_in_schema = True                                                              │ │
│                                                                                                 │                         methods = ['POST']                                                          │ │
│                                                                                                 │                            name = None                                                              │ │
│                                                                                                 │                   openapi_extra = None                                                              │ │
│                                                                                                 │                    operation_id = None                                                              │ │
│                                                                                                 │                            path = '/'                                                               │ │
│                                                                                                 │                  response_class = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cef0> │ │
│                                                                                                 │            response_description = 'Successful Response'                                             │ │
│                                                                                                 │                  response_model = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cec0> │ │
│                                                                                                 │         response_model_by_alias = True                                                              │ │
│                                                                                                 │          response_model_exclude = None                                                              │ │
│                                                                                                 │ response_model_exclude_defaults = False                                                             │ │
│                                                                                                 │     response_model_exclude_none = False                                                             │ │
│                                                                                                 │    response_model_exclude_unset = False                                                             │ │
│                                                                                                 │          response_model_include = None                                                              │ │
│                                                                                                 │                       responses = {}                                                                │ │
│                                                                                                 │            route_class_override = None                                                              │ │
│                                                                                                 │                            self = <fastapi.routing.APIRouter object at 0x1107d3560>                 │ │
│                                                                                                 │                     status_code = None                                                              │ │
│                                                                                                 │                         summary = None                                                              │ │
│                                                                                                 │                            tags = None                                                              │ │
│                                                                                                 ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi/routing.py:636 in __init__                                                                                    │
│                                                                                                                                                                                                         │
│    633 │   │   │   self.response_fields = {}                                                    ╭────────────────────────────────────────────── locals ───────────────────────────────────────────────╮ │
│    634 │   │                                                                                    │                       callbacks = []                                                                │ │
│    635 │   │   assert callable(endpoint), "An endpoint must be a callable"                      │                    dependencies = []                                                                │ │
│ ❱  636 │   │   self.dependant = get_dependant(                                                  │   dependency_overrides_provider = None                                                              │ │
│    637 │   │   │   path=self.path_format, call=self.endpoint, scope="function"                  │                      deprecated = None                                                              │ │
│    638 │   │   )                                                                                │                     description = None                                                              │ │
│    639 │   │   for depends in self.dependencies[::-1]:                                          │     generate_unique_id_function = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cf20> │ │
│                                                                                                 │               include_in_schema = True                                                              │ │
│                                                                                                 │                         methods = ['POST']                                                          │ │
│                                                                                                 │                            name = None                                                              │ │
│                                                                                                 │                   openapi_extra = None                                                              │ │
│                                                                                                 │                    operation_id = None                                                              │ │
│                                                                                                 │                            path = '/chsh/'                                                          │ │
│                                                                                                 │                  response_class = <fastapi.datastructures.DefaultPlaceholder object at 0x10757cef0> │ │
│                                                                                                 │            response_description = 'Successful Response'                                             │ │
│                                                                                                 │                 response_fields = {}                                                                │ │
│                                                                                                 │                  response_model = dict[str, float]                                                  │ │
│                                                                                                 │         response_model_by_alias = True                                                              │ │
│                                                                                                 │          response_model_exclude = None                                                              │ │
│                                                                                                 │ response_model_exclude_defaults = False                                                             │ │
│                                                                                                 │     response_model_exclude_none = False                                                             │ │
│                                                                                                 │    response_model_exclude_unset = False                                                             │ │
│                                                                                                 │          response_model_include = None                                                              │ │
│                                                                                                 │                   response_name = 'Response_chsh_chsh__post'                                        │ │
│                                                                                                 │                       responses = {}                                                                │ │
│                                                                                                 │               return_annotation = dict[str, float]                                                  │ │
│                                                                                                 │                            self = APIRoute(path='/chsh/', name='chsh', methods=['POST'])            │ │
│                                                                                                 │                     status_code = None                                                              │ │
│                                                                                                 │                         summary = None                                                              │ │
│                                                                                                 │                            tags = ['chsh']                                                          │ │
│                                                                                                 ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi/dependencies/utils.py:260 in get_dependant                                                                    │
│                                                                                                                                                                                                         │
│    257 │   │   dependant.security_requirements.append(security_requirement)                                                                                                                             │
│    258 │   for param_name, param in signature_params.items():                                                                                                                                           │
│    259 │   │   is_path_param = param_name in path_param_names                                                                                                                                           │
│ ❱  260 │   │   param_details = analyze_param(                                                                                                                                                           │
│    261 │   │   │   param_name=param_name,                                                                                                                                                               │
│    262 │   │   │   annotation=param.annotation,                                                                                                                                                         │
│    263 │   │   │   value=param.default,                                                                                                                                                                 │
│                                                                                                                                                                                                         │
│ ╭────────────────────────────────────────────────────────────────────────────────────────────── locals ───────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │          dependant = Dependant(                                                                                                                                                                     │ │
│ │                      │   path_params=[],                                                                                                                                                            │ │
│ │                      │   query_params=[                                                                                                                                                             │ │
│ │                      │   │   ModelField(field_info=Query(annotation=str, required=True, alias='follower_node_address', json_schema_extra={}), name='follower_node_address', mode='validation')      │ │
│ │                      │   ],                                                                                                                                                                         │ │
│ │                      │   header_params=[],                                                                                                                                                          │ │
│ │                      │   cookie_params=[],                                                                                                                                                          │ │
│ │                      │   body_params=[ModelField(field_info=Body(annotation=tuple[float, float], required=True, alias='basis', json_schema_extra={}), name='basis', mode='validation')],            │ │
│ │                      │   dependencies=[],                                                                                                                                                           │ │
│ │                      │   security_requirements=[],                                                                                                                                                  │ │
│ │                      │   name=None,                                                                                                                                                                 │ │
│ │                      │   call=<function chsh at 0x110895440>,                                                                                                                                       │ │
│ │                      │   request_param_name=None,                                                                                                                                                   │ │
│ │                      │   websocket_param_name=None,                                                                                                                                                 │ │
│ │                      │   http_connection_param_name=None,                                                                                                                                           │ │
│ │                      │   response_param_name=None,                                                                                                                                                  │ │
│ │                      │   background_tasks_param_name=None,                                                                                                                                          │ │
│ │                      │   security_scopes_param_name=None,                                                                                                                                           │ │
│ │                      │   security_scopes=None,                                                                                                                                                      │ │
│ │                      │   use_cache=True,                                                                                                                                                            │ │
│ │                      │   path='/chsh/',                                                                                                                                                             │ │
│ │                      │   scope='function'                                                                                                                                                           │ │
│ │                      )                                                                                                                                                                              │ │
│ │ endpoint_signature = <Signature (basis: tuple[float, float], follower_node_address: str, http_client: ClientDep, timetagger_address: str)>                                                          │ │
│ │      is_path_param = False                                                                                                                                                                          │ │
│ │               name = None                                                                                                                                                                           │ │
│ │              param = <Parameter "http_client: ClientDep">                                                                                                                                           │ │
│ │      param_details = ParamDetails(                                                                                                                                                                  │ │
│ │                      │   type_annotation=<class 'str'>,                                                                                                                                             │ │
│ │                      │   depends=None,                                                                                                                                                              │ │
│ │                      │   field=ModelField(                                                                                                                                                          │ │
│ │                      │   │   field_info=Query(annotation=str, required=True, alias='follower_node_address', json_schema_extra={}),                                                                  │ │
│ │                      │   │   name='follower_node_address',                                                                                                                                          │ │
│ │                      │   │   mode='validation'                                                                                                                                                      │ │
│ │                      │   )                                                                                                                                                                          │ │
│ │                      )                                                                                                                                                                              │ │
│ │         param_name = 'http_client'                                                                                                                                                                  │ │
│ │               path = '/chsh/'                                                                                                                                                                       │ │
│ │   path_param_names = set()                                                                                                                                                                          │ │
│ │              scope = 'function'                                                                                                                                                                     │ │
│ │    security_scopes = None                                                                                                                                                                           │ │
│ │   signature_params = mappingproxy({                                                                                                                                                                 │ │
│ │                      │   'basis': <Parameter "basis: tuple[float, float]">,                                                                                                                         │ │
│ │                      │   'follower_node_address': <Parameter "follower_node_address: str">,                                                                                                         │ │
│ │                      │   'http_client': <Parameter "http_client: ClientDep">,                                                                                                                       │ │
│ │                      │   'timetagger_address': <Parameter "timetagger_address: str">                                                                                                                │ │
│ │                      })                                                                                                                                                                             │ │
│ │          use_cache = True                                                                                                                                                                           │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi/dependencies/utils.py:502 in analyze_param                                                                    │
│                                                                                                                                                                                                         │
│    499 │   │   else:                                                                                                                                                                                    │
│    500 │   │   │   alias = field_info.alias or param_name                                                                                                                                               │
│    501 │   │   field_info.alias = alias                                                                                                                                                                 │
│ ❱  502 │   │   field = create_model_field(                                                                                                                                                              │
│    503 │   │   │   name=param_name,                                                                                                                                                                     │
│    504 │   │   │   type_=use_annotation_from_field_info,                                                                                                                                                │
│    505 │   │   │   default=field_info.default,                                                                                                                                                          │
│                                                                                                                                                                                                         │
│ ╭──────────────────────────────────────────────────────── locals ────────────────────────────────────────────────────────╮                                                                              │
│ │                          alias = 'http_client'                                                                         │                                                                              │
│ │                     annotation = ClientDep                                                                             │                                                                              │
│ │                  default_value = PydanticUndefined                                                                     │                                                                              │
│ │                        depends = None                                                                                  │                                                                              │
│ │                          field = None                                                                                  │                                                                              │
│ │                     field_info = Query(annotation=ClientDep, required=True, alias='http_client', json_schema_extra={}) │                                                                              │
│ │                  is_path_param = False                                                                                 │                                                                              │
│ │                     param_name = 'http_client'                                                                         │                                                                              │
│ │                type_annotation = ClientDep                                                                             │                                                                              │
│ │                 use_annotation = ClientDep                                                                             │                                                                              │
│ │ use_annotation_from_field_info = ClientDep                                                                             │                                                                              │
│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                                                              │
│                                                                                                                                                                                                         │
│ /Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi/utils.py:124 in create_model_field                                                                            │
│                                                                                                                                                                                                         │
│   121 │   │   try:                                                                                                                                                                                      │
│   122 │   │   │   return v2.ModelField(**kwargs)  # type: ignore[return-value,arg-type]                                                                                                                 │
│   123 │   │   except PydanticSchemaGenerationError:                                                                                                                                                     │
│ ❱ 124 │   │   │   raise fastapi.exceptions.FastAPIError(_invalid_args_message) from None                                                                                                                │
│   125 │   # Pydantic v2 is not installed, but it's not a Pydantic v1 ModelField, it could be                                                                                                            │
│   126 │   # a Pydantic v1 type, like a constrained int                                                                                                                                                  │
│   127 │   from fastapi._compat import v1                                                                                                                                                                │
│                                                                                                                                                                                                         │
│ ╭─────────────────────────────────────────────────────────────────────────────── locals ────────────────────────────────────────────────────────────────────────────────╮                               │
│ │            alias = 'http_client'                                                                                                                                      │                               │
│ │ class_validators = {}                                                                                                                                                 │                               │
│ │          default = PydanticUndefined                                                                                                                                  │                               │
│ │       field_info = Query(annotation=ClientDep, required=True, alias='http_client', json_schema_extra={})                                                              │                               │
│ │           kwargs = {'mode': 'validation', 'name': 'http_client', 'field_info': Query(annotation=ClientDep, required=True, alias='http_client', json_schema_extra={})} │                               │
│ │             mode = 'validation'                                                                                                                                       │                               │
│ │     model_config = None                                                                                                                                               │                               │
│ │             name = 'http_client'                                                                                                                                      │                               │
│ │         required = True                                                                                                                                               │                               │
│ │            type_ = ClientDep                                                                                                                                          │                               │
│ │    v1_field_info = Query(annotation=ClientDep, required=True, alias='http_client', json_schema_extra={})                                                              │                               │
│ │        v1_kwargs = {                                                                                                                                                  │                               │
│ │                    │   'name': 'http_client',                                                                                                                         │                               │
│ │                    │   'field_info': Query(annotation=ClientDep, required=True, alias='http_client', json_schema_extra={}),                                           │                               │
│ │                    │   'type_': ClientDep,                                                                                                                            │                               │
│ │                    │   'class_validators': {},                                                                                                                        │                               │
│ │                    │   'default': PydanticUndefined,                                                                                                                  │                               │
│ │                    │   'required': True,                                                                                                                              │                               │
│ │                    │   'model_config': <class 'pydantic.v1.config.BaseConfig'>,                                                                                       │                               │
│ │                    │   'alias': 'http_client'                                                                                                                         │                               │
│ │                    }                                                                                                                                                  │                               │
│ │               v2 = <module 'fastapi._compat.v2' from '/Users/marcosf2/Documents/github/PQN/pqn-stack/.venv/lib/python3.12/site-packages/fastapi/_compat/v2.py'>       │                               │
│ │          version = 'auto'                                                                                                                                             │                               │
│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                               │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
FastAPIError: Invalid args for response field! Hint: check that {type_} is a valid Pydantic field type. If you are using a return type annotation that is not a valid Pydantic field (e.g. Union[Response, 
dict, None]) you can disable generating the response model from the type annotation with the path operation decorator parameter response_model=None. Read more: 
https://fastapi.tiangolo.com/tutorial/response-model/



async def get_instrument_client() -> AsyncGenerator[Client, None]:
async with Client(host=settings.router_address, port=settings.router_port, timeout=60) as client:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a way of specifying the timeout for for different instrument clients. Specially if we are using this to get the timetagger since that timeout is longer than other instruments.



async def get_instrument_client() -> AsyncGenerator[Client, None]:
async with Client(host=settings.router_address, port=settings.router_port, timeout=60) as client:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeout is still in ms, if we want to switch to seconds, we need to make that conversion in the client file itself before setting the default

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants